package com.viewsky.base.back.controller.user;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import com.viewsky.base.back.bean.LoginUser;
import com.viewsky.base.back.bean.Result;
import com.viewsky.base.back.controller.BaseController;
import com.viewsky.base.back.service.user.UserService;
import com.viewsky.base.back.util.Constant;

import io.jsonwebtoken.ExpiredJwtException;
import io.jsonwebtoken.SignatureException;

@RestController
public class UserController extends BaseController
{
	@Resource(name="userService")
	private UserService userService;
	
	@PostMapping("/login")
	public Result Login(@RequestBody LoginUser loginUser, 
			HttpSession session, HttpServletResponse response) throws Exception
	{
		Result result = new Result();
		
		try
		{
			loginUser = userService.authenticateUser(loginUser);			
			
			if(loginUser == null)
			{
				result.setServer(getServer());
				result.setCode(Constant.ResultCode.ERROR_PASSWORD);
				result.setData("错误的用户名或密码");
			}
			else 
			{
				loginUser.setClientIp(getClientIp());
				result = bindUser(loginUser, session, response); 
			}
		} 
		catch(Exception e)
		{
			String strMessage = "服务器：" + getServer() +
					"，POST方式/login，" +
					"验证用户登录报错：" + e.toString();
			
			logger.error(strMessage);
			throw new Exception(strMessage);
		}
		
		return result;
	}
	
	/* 用于系统生成带有token的链接，由用户直接在浏览器中访问，
	 * 把token中包含的用户信息放入session或在header中加入token */
	@GetMapping("/loginByToken")
	public Result loginByToken(@RequestParam("token") String strToken, 
			HttpSession session, HttpServletResponse response) throws Exception
	{
		Result result = new Result();
		
		try
		{
			LoginUser loginUser = userService.authenticateUser(strToken); 
			
			loginUser.setClientIp(getClientIp());
			result = bindUser(loginUser, session, response);
		}
		catch(ExpiredJwtException e)
		{
			result.setServer(getServer());
			result.setCode(Constant.ResultCode.TOKEN_EXPIRED);
			result.setData("链接已经超时，请重新登录");
		}
		catch(SignatureException e)
		{
			result.setServer(getServer());
			result.setCode(Constant.ResultCode.TOKEN_MODIFIED);
			result.setData("链接已被篡改，请重新登录");
		}
		catch(Exception e)
		{
			String strMessage = "服务器：" + getServer() +
					"，GET方式/loginByToken，" +
					"根据token登录报错：" + e.toString();
			
			logger.error(strMessage);
			throw new Exception(strMessage);
		}
		
		return result;
	}
	
	@PostMapping("/logout")
	public Result Logout(HttpSession session, 
			@RequestParam("userId") String userId) throws Exception
	{
		System.err.println(userId);
		
		Result result = new Result();
		
		try
		{
			session.invalidate();
			
			result.setServer(getServer());
			result.setCode(Constant.ResultCode.SUCCESS);
			result.setData("注销用户成功");
		}
		catch(Exception e)
		{
			String strMessage = "服务器：" + getServer() +
					"，POST方式/logout，" +
					"注销用户报错：" + e.toString();
			
			logger.error(strMessage);
			throw new Exception(strMessage);
		}
		
		return result;
	}
	
	private Result bindUser(LoginUser loginUser, HttpSession session,
			HttpServletResponse response) throws Exception
	{
		Result result = new Result();
		
		if(Constant.AuthenticationMethod.SESSION.equals(strAuthenticationMethod))
		{
			session.setAttribute("loginUser", loginUser);
			
			result.setServer(getServer());
			result.setCode(Constant.ResultCode.SUCCESS);	
			result.setData(loginUser);
		}
		else if(Constant.AuthenticationMethod.TOKEN.equals(strAuthenticationMethod))
		{
			String strToken = userService.generateToken(loginUser);
			response.addHeader("Authorization", Constant.DEF_TOKEN_HEADER + strToken);
			response.addHeader("Access-Control-Expose-Headers", "Authorization");
			response.addHeader("Cache-Control", "no-store");
			
			result.setServer(getServer());
			result.setCode(Constant.ResultCode.SUCCESS);
			result.setData(loginUser);
		}
		else 
		{
			result.setServer(getServer());
			result.setCode(Constant.ResultCode.INNER_ERROR);	
			result.setData("配置的config.authentication.method不合法");
		}
		
		return result;
	}
}
